package cn.sc.summer.mybatis.base;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.annotation.InterceptorIgnore;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import cn.sc.summer.constant.model.PageParam;
import cn.sc.summer.constant.model.PageResult;
import cn.sc.summer.constant.mybatisplus.SqlConstant;
import cn.sc.summer.exception.enums.BaseExceptionEnum;
import cn.sc.summer.mybatis.util.PageUtil;
import icu.mhb.mybatisplus.plugln.base.mapper.JoinBaseMapper;
import org.apache.ibatis.annotations.Param;

import java.util.Collection;
import java.util.List;

/**
 * @author a-xin
 * @className SuperMapper
 * @description Mapper父接口  Mapper 继承该接口后，无需编写 mapper.xml 文件，即可获得CRUD功能
 * @date 2022-05-30 10:38
 */
public interface SuperMapper<T> extends JoinBaseMapper<T> {

    /**
     * 批量插入:mybatis plus自带，仅适用于mysql
     *
     * @param entityList 实体列表
     */
    @InterceptorIgnore(others = "dataOperation@true")
    void insertBatchSomeColumn(Collection<T> entityList);

    /**
     * 批量新增
     *
     * @param entityList 实体列表
     * @return 影响行数
     */
    Integer insertBatch(@Param("list") Collection<T> entityList);

    /**
     * 批量更新
     *
     * @param entityList 实体列表
     * @return 影响行数
     */
    Integer updateBatch(@Param("list") Collection<T> entityList);

    /**
     * 获取所有数据
     *
     * @return 所有数据
     */
    default List<T> selectList() {
        return selectList(new LambdaQueryWrapper<>());
    }

    /**
     * 获取list数据
     *
     * @param field 属性
     * @param value 值
     * @return 查询list
     */
    default List<T> selectList(SFunction<T, ?> field, Object value) {
        return selectList(new LambdaQueryWrapper<T>().eq(field, value));
    }

    /**
     * 分页查找
     *
     * @param page         分页参数
     * @param queryWrapper 条件查询
     * @param <P>          分页参数类型
     * @return 分页查询结果
     */
    default <P extends PageParam> Page<T> selectPage(P page, Wrapper<T> queryWrapper) {
        Page<T> tPage = new Page<>();
        tPage.setCurrent(page.getCurrent() == 0 ? 1 : page.getCurrent());
        tPage.setSize(page.getSize());
        return selectPage(tPage, queryWrapper);
    }

    /**
     * 分页查找，并转换成指定的类型
     *
     * @param page         分页参数
     * @param queryWrapper 条件查询
     * @param clazz        返回类型
     * @param <F>          需要转换的类型
     * @param <P>          分页参数类型
     * @return 分页查询结果
     */
    default <F, P extends PageParam> PageResult<F> selectPage(P page, Wrapper<T> queryWrapper, Class<F> clazz) {
        Page<T> tPage = new Page<>();
        tPage.setCurrent(page.getCurrent() == 0 ? 1 : page.getCurrent());
        tPage.setSize(page.getSize());
        return PageUtil.pageToResult(selectPage(tPage, queryWrapper), clazz);
    }

    /**
     * 查询是否存在，存在则报错，queryWrapper匹配limit 1，查询到一个结果就返回，避免全盘查询
     *
     * @param queryWrapper 条件查询
     * @param message      报错信息
     */
    default void exceptionIfExit(LambdaQueryWrapper<T> queryWrapper, String message) {
        List<T> ts = selectList(queryWrapper.last(SqlConstant.LIMIT_ONE));
        BaseExceptionEnum.CHECK_EXCEPTION.predicate(ts, CollUtil::isNotEmpty, message);
    }

}
